package com.baofu.paycore.biz.engine.processor.impl;

import com.baofu.paycore.biz.engine.command.impl.BankConfirmCommand;
import com.baofu.paycore.biz.engine.processor.BaseProcessor;
import com.baofu.paycore.biz.engine.result.CommandResult;
import com.baofu.paycore.biz.enums.CommandProcessorEnum;
import com.baofu.paycore.service.facade.RechargeServiceFacade;
import com.baofu.paycore.service.facade.enums.PayStatusEnums;
import com.baofu.paycore.service.facade.enums.RequestSystemEnum;
import com.baofu.paycore.service.facade.model.recharge.RechargeConfirmDTO;
import com.baofu.paycore.service.facade.model.recharge.RechargeResDTO;
import com.system.commons.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.jboss.logging.MDC;
import org.slf4j.helpers.SystemMarker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 银行确认处理器
 * <p>
 *     1、处理快捷确认
 * </p>
 *
 * User: Xiachen Date: 2017/04/06  Version: 1.0
 */
@Slf4j
@Service
public class BankConfirmProcessor implements BaseProcessor<BankConfirmCommand> {

    /** 充值服务 */
    @Autowired
    private RechargeServiceFacade rechargeService;

    /**
     * 获取处理器类型
     *
     * @return 命令处理器
     */
    @Override
    public CommandProcessorEnum getProcessorType() {
        return CommandProcessorEnum.BANK_CONFIRM_PROCESSOR;
    }

    /**
     * 执行特定支付工具的特定支付类型的批量支付命令，并返回相应的结果
     *
     * @param bankCommand 支付命令
     * @return         指令执行结果
     */
    @Override
    public Map<String, CommandResult> doProcess(BankConfirmCommand bankCommand) {
        log.debug("进入银行卡类处理器：commands={}", bankCommand);
        Map<String, CommandResult> result = new HashMap<>();
        try {
            RechargeConfirmDTO rechargeDTO = convertToRechargeDTO(bankCommand);
            log.info("快捷确认充值请求参数，request={}", rechargeDTO);
            Result<RechargeResDTO> rechargeResDTO =
                    rechargeService.rechargeConfirm(rechargeDTO,bankCommand.getTraceLogId());

            //由于调用充值facade接口，而facade接口会商户MDC中存放的transLogId，需要再次放入
            MDC.put(SystemMarker.TRACE_LOG_ID, bankCommand.getTraceLogId());
            log.info("快捷确认充值请求结果，result={}", rechargeResDTO);

            CommandResult payResult = new CommandResult();
            if (rechargeResDTO != null && rechargeResDTO.isSuccess()) {
                RechargeResDTO rechargeResult = rechargeResDTO.getResult();
                payResult.setRealRtnFlag(rechargeResult.isRealRtnFlag());
                payResult.setStatus(rechargeResult.getStatus());
                payResult.setResultCode(rechargeResult.getErrorCode());
                payResult.setResultMsg(rechargeResult.getErrorMsg());
                payResult.setResponseDate(rechargeResult.getRespDate());
                payResult.setResultVO(rechargeResult);
                payResult.setResponseNo(rechargeResult.getPayNo());
            }
            payResult.setCommand(bankCommand);
            result.put(bankCommand.getCommandNo(), payResult);
        } catch (Exception e) {
            log.error("快捷确认充值指令处理失败{}", e);
            CommandResult payResult = new CommandResult();
            payResult.setStatus(PayStatusEnums.FAIL.getCode());
            payResult.setRealRtnFlag(false);
            result.put(bankCommand.getCommandNo(), payResult);
        }
        return result;
    }

    /**
     * 执行取消方法
     *
     * @param commands 支付命令
     * @return v        指令执行结果
     */
    @Override
    public Map<String, CommandResult> doCancel(List<BankConfirmCommand> commands) {
        return null;
    }

    /**
     * 银行充值
     *
     * @param bankCommand 银行类支付指令
     * @return            银行快捷请求参数
     */
    protected RechargeConfirmDTO convertToRechargeDTO(BankConfirmCommand bankCommand) {
        RechargeConfirmDTO dto = new RechargeConfirmDTO();
        dto.setRequestBizNo(bankCommand.getRequestBizNo());
        dto.setRequestSystem(RequestSystemEnum.PAYCORE.getCode());//区分是支付调用的充值还是其他系统调用的充值
        dto.setRequestOrderNo(bankCommand.getRequestOrderNo());
        dto.setSmsCode(bankCommand.getSmsCode());
        return dto;
    }

}
